Add animation of activation by, on activate, pressing the button, and
authorOwen Taylor <otaylor@redhat.com>
Tue, 6 Mar 2001 15:51:10 +0000 (15:51 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Tue, 6 Mar 2001 15:51:10 +0000 (15:51 +0000)
Tue Mar  6 10:45:45 2001  Owen Taylor  <otaylor@redhat.com>

* gtk/gtkbutton.c: Add animation of activation by, on
activate, pressing the button, and adding a timeout that
releases the button after 250ms or on key release and
emits ::clicked. (#51501)

* gtk/gtkdialog.c: Bit of a hack - for buttons in the
action area, we connect to ::clicked instead of ::activate
so the dialog stays up through the animation.

Mon Mar  5 16:38:15 2001  Owen Taylor  <otaylor@redhat.com>

* gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only
check the ignore_enter flag for the menu shell that
the item is actually a child of, not for attached
submenus. (#51536)

ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkbutton.c
gtk/gtkbutton.h
gtk/gtkdialog.c
gtk/gtkmenushell.c

index ab3aafd3058c6d2b399a92ff6d7b0db4e1f45199..8508ed70a825b37b2340c9be08485437e0becd0e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+Tue Mar  6 10:45:45 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkbutton.c: Add animation of activation by, on 
+       activate, pressing the button, and adding a timeout that 
+       releases the button after 250ms or on key release and
+       emits ::clicked. (#51501)
+
+       * gtk/gtkdialog.c: Bit of a hack - for buttons in the
+       action area, we connect to ::clicked instead of ::activate
+       so the dialog stays up through the animation.
+
+Mon Mar  5 16:38:15 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only
+       check the ignore_enter flag for the menu shell that
+       the item is actually a child of, not for attached
+       submenus. (#51536)
+
+Tue Feb 27 02:16:14 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmain.c (gtk_propagate_event): Only do special
+        special key-press grab handling for widgets within
+        GtkWindows. Otherwise, fall through to normal case.
+
+        This prevents key events being sent twice to GtkInvisible
+        widgets, which can cause all sorts of mischief.
+
+Fri Feb  2 13:20:12 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmain.c (gtk_propagate_event): When a grab
+       widget is in effect, give the grab widget a first
+       crack at KEY_PRESS/RELEASE events. (#424)
+
 2001-03-06  James Henstridge  <james@daa.com.au>
 
        * gtk/gtkwidget.c (gtk_widget_class_init): set the class closure
@@ -55,6 +88,7 @@ Mon Mar  5 14:38:54 2001  Jonathan Blandford  <jrb@redhat.com>
        parent_class pointer in pixbuf_style_class_init().
        (Will commit the fix to the pixbuf-engine too).
 
+>>>>>>> 1.1779
 2001-03-05  Alexander Larsson  <alexl@redhat.com>
 
        * gdk/gdkwindow.h:
index ab3aafd3058c6d2b399a92ff6d7b0db4e1f45199..8508ed70a825b37b2340c9be08485437e0becd0e 100644 (file)
@@ -1,3 +1,36 @@
+Tue Mar  6 10:45:45 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkbutton.c: Add animation of activation by, on 
+       activate, pressing the button, and adding a timeout that 
+       releases the button after 250ms or on key release and
+       emits ::clicked. (#51501)
+
+       * gtk/gtkdialog.c: Bit of a hack - for buttons in the
+       action area, we connect to ::clicked instead of ::activate
+       so the dialog stays up through the animation.
+
+Mon Mar  5 16:38:15 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only
+       check the ignore_enter flag for the menu shell that
+       the item is actually a child of, not for attached
+       submenus. (#51536)
+
+Tue Feb 27 02:16:14 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmain.c (gtk_propagate_event): Only do special
+        special key-press grab handling for widgets within
+        GtkWindows. Otherwise, fall through to normal case.
+
+        This prevents key events being sent twice to GtkInvisible
+        widgets, which can cause all sorts of mischief.
+
+Fri Feb  2 13:20:12 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmain.c (gtk_propagate_event): When a grab
+       widget is in effect, give the grab widget a first
+       crack at KEY_PRESS/RELEASE events. (#424)
+
 2001-03-06  James Henstridge  <james@daa.com.au>
 
        * gtk/gtkwidget.c (gtk_widget_class_init): set the class closure
@@ -55,6 +88,7 @@ Mon Mar  5 14:38:54 2001  Jonathan Blandford  <jrb@redhat.com>
        parent_class pointer in pixbuf_style_class_init().
        (Will commit the fix to the pixbuf-engine too).
 
+>>>>>>> 1.1779
 2001-03-05  Alexander Larsson  <alexl@redhat.com>
 
        * gdk/gdkwindow.h:
index ab3aafd3058c6d2b399a92ff6d7b0db4e1f45199..8508ed70a825b37b2340c9be08485437e0becd0e 100644 (file)
@@ -1,3 +1,36 @@
+Tue Mar  6 10:45:45 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkbutton.c: Add animation of activation by, on 
+       activate, pressing the button, and adding a timeout that 
+       releases the button after 250ms or on key release and
+       emits ::clicked. (#51501)
+
+       * gtk/gtkdialog.c: Bit of a hack - for buttons in the
+       action area, we connect to ::clicked instead of ::activate
+       so the dialog stays up through the animation.
+
+Mon Mar  5 16:38:15 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only
+       check the ignore_enter flag for the menu shell that
+       the item is actually a child of, not for attached
+       submenus. (#51536)
+
+Tue Feb 27 02:16:14 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmain.c (gtk_propagate_event): Only do special
+        special key-press grab handling for widgets within
+        GtkWindows. Otherwise, fall through to normal case.
+
+        This prevents key events being sent twice to GtkInvisible
+        widgets, which can cause all sorts of mischief.
+
+Fri Feb  2 13:20:12 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmain.c (gtk_propagate_event): When a grab
+       widget is in effect, give the grab widget a first
+       crack at KEY_PRESS/RELEASE events. (#424)
+
 2001-03-06  James Henstridge  <james@daa.com.au>
 
        * gtk/gtkwidget.c (gtk_widget_class_init): set the class closure
@@ -55,6 +88,7 @@ Mon Mar  5 14:38:54 2001  Jonathan Blandford  <jrb@redhat.com>
        parent_class pointer in pixbuf_style_class_init().
        (Will commit the fix to the pixbuf-engine too).
 
+>>>>>>> 1.1779
 2001-03-05  Alexander Larsson  <alexl@redhat.com>
 
        * gdk/gdkwindow.h:
index ab3aafd3058c6d2b399a92ff6d7b0db4e1f45199..8508ed70a825b37b2340c9be08485437e0becd0e 100644 (file)
@@ -1,3 +1,36 @@
+Tue Mar  6 10:45:45 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkbutton.c: Add animation of activation by, on 
+       activate, pressing the button, and adding a timeout that 
+       releases the button after 250ms or on key release and
+       emits ::clicked. (#51501)
+
+       * gtk/gtkdialog.c: Bit of a hack - for buttons in the
+       action area, we connect to ::clicked instead of ::activate
+       so the dialog stays up through the animation.
+
+Mon Mar  5 16:38:15 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only
+       check the ignore_enter flag for the menu shell that
+       the item is actually a child of, not for attached
+       submenus. (#51536)
+
+Tue Feb 27 02:16:14 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmain.c (gtk_propagate_event): Only do special
+        special key-press grab handling for widgets within
+        GtkWindows. Otherwise, fall through to normal case.
+
+        This prevents key events being sent twice to GtkInvisible
+        widgets, which can cause all sorts of mischief.
+
+Fri Feb  2 13:20:12 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmain.c (gtk_propagate_event): When a grab
+       widget is in effect, give the grab widget a first
+       crack at KEY_PRESS/RELEASE events. (#424)
+
 2001-03-06  James Henstridge  <james@daa.com.au>
 
        * gtk/gtkwidget.c (gtk_widget_class_init): set the class closure
@@ -55,6 +88,7 @@ Mon Mar  5 14:38:54 2001  Jonathan Blandford  <jrb@redhat.com>
        parent_class pointer in pixbuf_style_class_init().
        (Will commit the fix to the pixbuf-engine too).
 
+>>>>>>> 1.1779
 2001-03-05  Alexander Larsson  <alexl@redhat.com>
 
        * gdk/gdkwindow.h:
index ab3aafd3058c6d2b399a92ff6d7b0db4e1f45199..8508ed70a825b37b2340c9be08485437e0becd0e 100644 (file)
@@ -1,3 +1,36 @@
+Tue Mar  6 10:45:45 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkbutton.c: Add animation of activation by, on 
+       activate, pressing the button, and adding a timeout that 
+       releases the button after 250ms or on key release and
+       emits ::clicked. (#51501)
+
+       * gtk/gtkdialog.c: Bit of a hack - for buttons in the
+       action area, we connect to ::clicked instead of ::activate
+       so the dialog stays up through the animation.
+
+Mon Mar  5 16:38:15 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only
+       check the ignore_enter flag for the menu shell that
+       the item is actually a child of, not for attached
+       submenus. (#51536)
+
+Tue Feb 27 02:16:14 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmain.c (gtk_propagate_event): Only do special
+        special key-press grab handling for widgets within
+        GtkWindows. Otherwise, fall through to normal case.
+
+        This prevents key events being sent twice to GtkInvisible
+        widgets, which can cause all sorts of mischief.
+
+Fri Feb  2 13:20:12 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmain.c (gtk_propagate_event): When a grab
+       widget is in effect, give the grab widget a first
+       crack at KEY_PRESS/RELEASE events. (#424)
+
 2001-03-06  James Henstridge  <james@daa.com.au>
 
        * gtk/gtkwidget.c (gtk_widget_class_init): set the class closure
@@ -55,6 +88,7 @@ Mon Mar  5 14:38:54 2001  Jonathan Blandford  <jrb@redhat.com>
        parent_class pointer in pixbuf_style_class_init().
        (Will commit the fix to the pixbuf-engine too).
 
+>>>>>>> 1.1779
 2001-03-05  Alexander Larsson  <alexl@redhat.com>
 
        * gdk/gdkwindow.h:
index ab3aafd3058c6d2b399a92ff6d7b0db4e1f45199..8508ed70a825b37b2340c9be08485437e0becd0e 100644 (file)
@@ -1,3 +1,36 @@
+Tue Mar  6 10:45:45 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkbutton.c: Add animation of activation by, on 
+       activate, pressing the button, and adding a timeout that 
+       releases the button after 250ms or on key release and
+       emits ::clicked. (#51501)
+
+       * gtk/gtkdialog.c: Bit of a hack - for buttons in the
+       action area, we connect to ::clicked instead of ::activate
+       so the dialog stays up through the animation.
+
+Mon Mar  5 16:38:15 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only
+       check the ignore_enter flag for the menu shell that
+       the item is actually a child of, not for attached
+       submenus. (#51536)
+
+Tue Feb 27 02:16:14 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmain.c (gtk_propagate_event): Only do special
+        special key-press grab handling for widgets within
+        GtkWindows. Otherwise, fall through to normal case.
+
+        This prevents key events being sent twice to GtkInvisible
+        widgets, which can cause all sorts of mischief.
+
+Fri Feb  2 13:20:12 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmain.c (gtk_propagate_event): When a grab
+       widget is in effect, give the grab widget a first
+       crack at KEY_PRESS/RELEASE events. (#424)
+
 2001-03-06  James Henstridge  <james@daa.com.au>
 
        * gtk/gtkwidget.c (gtk_widget_class_init): set the class closure
@@ -55,6 +88,7 @@ Mon Mar  5 14:38:54 2001  Jonathan Blandford  <jrb@redhat.com>
        parent_class pointer in pixbuf_style_class_init().
        (Will commit the fix to the pixbuf-engine too).
 
+>>>>>>> 1.1779
 2001-03-05  Alexander Larsson  <alexl@redhat.com>
 
        * gdk/gdkwindow.h:
index ab3aafd3058c6d2b399a92ff6d7b0db4e1f45199..8508ed70a825b37b2340c9be08485437e0becd0e 100644 (file)
@@ -1,3 +1,36 @@
+Tue Mar  6 10:45:45 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkbutton.c: Add animation of activation by, on 
+       activate, pressing the button, and adding a timeout that 
+       releases the button after 250ms or on key release and
+       emits ::clicked. (#51501)
+
+       * gtk/gtkdialog.c: Bit of a hack - for buttons in the
+       action area, we connect to ::clicked instead of ::activate
+       so the dialog stays up through the animation.
+
+Mon Mar  5 16:38:15 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only
+       check the ignore_enter flag for the menu shell that
+       the item is actually a child of, not for attached
+       submenus. (#51536)
+
+Tue Feb 27 02:16:14 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmain.c (gtk_propagate_event): Only do special
+        special key-press grab handling for widgets within
+        GtkWindows. Otherwise, fall through to normal case.
+
+        This prevents key events being sent twice to GtkInvisible
+        widgets, which can cause all sorts of mischief.
+
+Fri Feb  2 13:20:12 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkmain.c (gtk_propagate_event): When a grab
+       widget is in effect, give the grab widget a first
+       crack at KEY_PRESS/RELEASE events. (#424)
+
 2001-03-06  James Henstridge  <james@daa.com.au>
 
        * gtk/gtkwidget.c (gtk_widget_class_init): set the class closure
@@ -55,6 +88,7 @@ Mon Mar  5 14:38:54 2001  Jonathan Blandford  <jrb@redhat.com>
        parent_class pointer in pixbuf_style_class_init().
        (Will commit the fix to the pixbuf-engine too).
 
+>>>>>>> 1.1779
 2001-03-05  Alexander Larsson  <alexl@redhat.com>
 
        * gdk/gdkwindow.h:
index d756af1ba58c4451aa63d47801e482a00577e1b9..ecdd7b5a0e6098357eca5ccf9751a8210f7aef68 100644 (file)
 #define DEFAULT_TOP_POS   4
 #define DEFAULT_SPACING   7
 
+/* Time out before giving up on getting a key release when animatng
+ * the close button.
+ */
+#define ACTIVATE_TIMEOUT 250
 
 enum {
   PRESSED,
@@ -46,6 +50,7 @@ enum {
   CLICKED,
   ENTER,
   LEAVE,
+  ACTIVATE,
   LAST_SIGNAL
 };
 
@@ -55,8 +60,6 @@ enum {
   ARG_RELIEF
 };
 
-
-
 static void gtk_button_class_init     (GtkButtonClass   *klass);
 static void gtk_button_init           (GtkButton        *button);
 static void gtk_button_set_arg        (GtkObject        *object,
@@ -66,6 +69,7 @@ static void gtk_button_get_arg        (GtkObject        *object,
                                       GtkArg           *arg,
                                       guint             arg_id);
 static void gtk_button_realize        (GtkWidget        *widget);
+static void gtk_button_unrealize      (GtkWidget        *widget);
 static void gtk_button_size_request   (GtkWidget        *widget,
                                       GtkRequisition   *requisition);
 static void gtk_button_size_allocate  (GtkWidget        *widget,
@@ -78,6 +82,8 @@ static gint gtk_button_button_press   (GtkWidget        *widget,
                                       GdkEventButton   *event);
 static gint gtk_button_button_release (GtkWidget        *widget,
                                       GdkEventButton   *event);
+static gint gtk_button_key_release    (GtkWidget        *widget,
+                                      GdkEventKey      *event);
 static gint gtk_button_enter_notify   (GtkWidget        *widget,
                                       GdkEventCrossing *event);
 static gint gtk_button_leave_notify   (GtkWidget        *widget,
@@ -90,8 +96,11 @@ static void gtk_real_button_pressed   (GtkButton        *button);
 static void gtk_real_button_released  (GtkButton        *button);
 static void gtk_real_button_enter     (GtkButton        *button);
 static void gtk_real_button_leave     (GtkButton        *button);
+static void gtk_real_button_activate (GtkButton         *button);
 static GtkType gtk_button_child_type  (GtkContainer     *container);
 
+static void gtk_button_finish_activate (GtkButton *button,
+                                       gboolean   do_it);
 
 static GtkBinClass *parent_class = NULL;
 static guint button_signals[LAST_SIGNAL] = { 0 };
@@ -141,11 +150,13 @@ gtk_button_class_init (GtkButtonClass *klass)
   object_class->get_arg = gtk_button_get_arg;
 
   widget_class->realize = gtk_button_realize;
+  widget_class->unrealize = gtk_button_unrealize;
   widget_class->size_request = gtk_button_size_request;
   widget_class->size_allocate = gtk_button_size_allocate;
   widget_class->expose_event = gtk_button_expose;
   widget_class->button_press_event = gtk_button_button_press;
   widget_class->button_release_event = gtk_button_button_release;
+  widget_class->key_release_event = gtk_button_key_release;
   widget_class->enter_notify_event = gtk_button_enter_notify;
   widget_class->leave_notify_event = gtk_button_leave_notify;
 
@@ -158,6 +169,7 @@ gtk_button_class_init (GtkButtonClass *klass)
   klass->clicked = NULL;
   klass->enter = gtk_real_button_enter;
   klass->leave = gtk_real_button_leave;
+  klass->activate = gtk_real_button_activate;
 
   gtk_object_add_arg_type ("GtkButton::label", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_LABEL);
   gtk_object_add_arg_type ("GtkButton::relief", GTK_TYPE_RELIEF_STYLE, GTK_ARG_READWRITE, ARG_RELIEF);
@@ -183,7 +195,6 @@ gtk_button_class_init (GtkButtonClass *klass)
                     GTK_SIGNAL_OFFSET (GtkButtonClass, clicked),
                     gtk_marshal_VOID__VOID,
                    GTK_TYPE_NONE, 0);
-  widget_class->activate_signal = button_signals[CLICKED];
   button_signals[ENTER] =
     gtk_signal_new ("enter",
                     GTK_RUN_FIRST,
@@ -198,6 +209,14 @@ gtk_button_class_init (GtkButtonClass *klass)
                     GTK_SIGNAL_OFFSET (GtkButtonClass, leave),
                     gtk_marshal_VOID__VOID,
                    GTK_TYPE_NONE, 0);
+  button_signals[ACTIVATE] =
+    gtk_signal_new ("activate",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GtkButtonClass, activate),
+                    gtk_marshal_VOID__VOID,
+                   GTK_TYPE_NONE, 0);
+  widget_class->activate_signal = button_signals[ACTIVATE];
 }
 
 static void
@@ -493,6 +512,17 @@ gtk_button_realize (GtkWidget *widget)
   gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
 }
 
+static void
+gtk_button_unrealize (GtkWidget *widget)
+{
+  GtkButton *button = GTK_BUTTON (widget);
+
+  if (button->activate_timeout)
+    gtk_button_finish_activate (button, FALSE);
+    
+  GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
+}
+
 static void
 gtk_button_size_request (GtkWidget      *widget,
                         GtkRequisition *requisition)
@@ -749,6 +779,23 @@ gtk_button_button_release (GtkWidget      *widget,
   return TRUE;
 }
 
+static gboolean
+gtk_button_key_release (GtkWidget   *widget,
+                       GdkEventKey *event)
+{
+  GtkButton *button = GTK_BUTTON (widget);
+
+  if (button->activate_timeout)
+    {
+      gtk_button_finish_activate (button, TRUE);
+      return TRUE;
+    }
+  else if (GTK_WIDGET_CLASS (parent_class)->key_release_event)
+    return GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
+  else
+    return FALSE;
+}
+
 static gint
 gtk_button_enter_notify (GtkWidget        *widget,
                         GdkEventCrossing *event)
@@ -831,6 +878,9 @@ gtk_real_button_pressed (GtkButton *button)
   g_return_if_fail (button != NULL);
   g_return_if_fail (GTK_IS_BUTTON (button));
 
+  if (button->activate_timeout)
+    return;
+  
   button->button_down = TRUE;
 
   new_state = (button->in_button ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL);
@@ -854,6 +904,9 @@ gtk_real_button_released (GtkButton *button)
     {
       button->button_down = FALSE;
 
+      if (button->activate_timeout)
+       return;
+  
       if (button->in_button)
        gtk_button_clicked (button);
 
@@ -880,6 +933,9 @@ gtk_real_button_enter (GtkButton *button)
 
   new_state = (button->button_down ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT);
 
+  if (button->activate_timeout)
+    return;
+  
   if (GTK_WIDGET_STATE (button) != new_state)
     {
       gtk_widget_set_state (GTK_WIDGET (button), new_state);
@@ -892,10 +948,66 @@ gtk_real_button_leave (GtkButton *button)
 {
   g_return_if_fail (button != NULL);
   g_return_if_fail (GTK_IS_BUTTON (button));
-
+  
+  if (button->activate_timeout)
+    return;
+  
   if (GTK_WIDGET_STATE (button) != GTK_STATE_NORMAL)
     {
       gtk_widget_set_state (GTK_WIDGET (button), GTK_STATE_NORMAL);
       gtk_widget_queue_draw (GTK_WIDGET (button));
     }
 }
+
+static gboolean
+button_activate_timeout (gpointer data)
+{
+  gtk_button_finish_activate (data, TRUE);
+
+  return FALSE;
+}
+
+static void
+gtk_real_button_activate (GtkButton *button)
+{
+  GtkWidget *widget = GTK_WIDGET (button);
+  
+  g_return_if_fail (button != NULL);
+  g_return_if_fail (GTK_IS_BUTTON (button));
+
+  if (GTK_WIDGET_REALIZED (button) && !button->activate_timeout)
+    {
+      if (gdk_keyboard_grab (widget->window, TRUE,
+                            gtk_get_current_event_time ()) == 0)
+       {
+         gtk_grab_add (widget);
+         
+         button->activate_timeout = g_timeout_add (ACTIVATE_TIMEOUT,
+                                                   button_activate_timeout,
+                                                   button);
+         button->button_down = TRUE;
+         gtk_widget_set_state (widget, GTK_STATE_ACTIVE);
+       }
+    }
+}
+
+static void
+gtk_button_finish_activate (GtkButton *button,
+                           gboolean   do_it)
+{
+  GtkWidget *widget = GTK_WIDGET (button);
+  
+  g_source_remove (button->activate_timeout);
+  button->activate_timeout = 0;
+
+  gdk_keyboard_ungrab (gtk_get_current_event_time ());
+  gtk_grab_remove (widget);
+
+  button->button_down = FALSE;
+  gtk_widget_set_state (GTK_WIDGET (button),
+                       button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL);
+
+  if (do_it)
+    gtk_button_clicked (button);
+}
+
index 0d8c676d09667a9e72f9908e98294bc128f0b9f7..553813994c869789dc6c2a25dc9f97c2a9e92432 100644 (file)
@@ -56,6 +56,8 @@ struct _GtkButton
                    * use GTK_BIN (button)->child instead
                    */;
 
+  guint activate_timeout;
+
   guint in_button : 1;
   guint button_down : 1;
   guint relief : 2;
@@ -70,6 +72,7 @@ struct _GtkButtonClass
   void (* clicked)  (GtkButton *button);
   void (* enter)    (GtkButton *button);
   void (* leave)    (GtkButton *button);
+  void (* activate) (GtkButton *button);
 };
 
 
index 85c3432bcd5684f826af3bbdf358994117fbaf2e..1742f567804839d7cebe682a3c44d4adc8399564 100644 (file)
@@ -340,6 +340,7 @@ gtk_dialog_add_action_widget  (GtkDialog *dialog,
                                gint       response_id)
 {
   ResponseData *ad;
+  gint signal_id = 0;
   
   g_return_if_fail (GTK_IS_DIALOG (dialog));
   g_return_if_fail (GTK_IS_WIDGET (child));
@@ -348,10 +349,16 @@ gtk_dialog_add_action_widget  (GtkDialog *dialog,
 
   ad->response_id = response_id;
 
-  if (GTK_WIDGET_GET_CLASS (child)->activate_signal != 0)
+  if (GTK_IS_BUTTON (child))
     {
-      const gchar* name =
-        gtk_signal_name (GTK_WIDGET_GET_CLASS (child)->activate_signal);
+      signal_id = g_signal_lookup ("clicked", GTK_TYPE_BUTTON);
+    }
+  else
+    signal_id = GTK_WIDGET_GET_CLASS (child)->activate_signal != 0;
+
+  if (signal_id)
+    {
+      const gchar* name = gtk_signal_name (signal_id);
 
       gtk_signal_connect_while_alive (GTK_OBJECT (child),
                                       name,
index 96765471f407880e724a666b3188e42d11b3a135..a59acf4a286b2f58e8ec4e39fc0e9609ae7d03fd 100644 (file)
@@ -585,7 +585,7 @@ gtk_menu_shell_enter_notify (GtkWidget        *widget,
 
   menu_shell = GTK_MENU_SHELL (widget);
 
-  if (menu_shell->active && !menu_shell->ignore_enter)
+  if (menu_shell->active)
     {
       menu_item = gtk_get_event_widget ((GdkEvent*) event);
 
@@ -596,6 +596,9 @@ gtk_menu_shell_enter_notify (GtkWidget        *widget,
          (menu_shell->active_menu_item != menu_item) &&
          GTK_IS_MENU_ITEM (menu_item))
        {
+         if (menu_shell->ignore_enter)
+           return TRUE;
+         
          if ((event->detail != GDK_NOTIFY_INFERIOR) &&
              (GTK_WIDGET_STATE (menu_item) != GTK_STATE_PRELIGHT))
            {